package cn.fansunion.leecode.intelligence;

import java.util.Map;
import java.util.Map.Entry;

import cn.fansunion.leecode.kit.Kit;

/**
 * 914. 卡牌分组 <br/>
 * 给定一副牌，每张牌上都写着一个整数。 <br/>
 * 
 * 此时，你需要选定一个数字 X，使我们可以将整副牌按下述规则分成 1 组或更多组： <br/>
 * 
 * 每组都有 X 张牌。 组内所有的牌上都写着相同的整数。 <br/>
 * 仅当你可选的 X >= 2 时返回 true。 <br/>
 * 
 * 来源：力扣（LeetCode） 链接：https://leetcode-cn.com/problems/x-of-a-kind-in-a-deck-of-cards 著作权归领扣网络所有。商业转载请联系官方授权，非商业转载请注明出处。
 * 
 * @author wen.lei@brgroup.com
 *
 *         2022-3-9
 */
public class XOfAKindInADeckOfCards {
    /*    示例 1：
    
    输入：deck = [1,2,3,4,4,3,2,1]
    输出：true
    解释：可行的分组是 [1,1]，[2,2]，[3,3]，[4,4]
    示例 2：
    
    输入：deck = [1,1,1,2,2,2,3,3]
    输出：false
    解释：没有满足要求的分组。
    
    提示：
    
    1 <= deck.length <= 104
    0 <= deck[i] < 104*/

    /**
     * 题目的意思：统计各个数出现的次数，然后求次数之间是否存在公约数
     * 
     * 
     */
    public boolean hasGroupsSizeX(int[] deck) {
        Map<Integer, Integer> countMap = Kit.countMap(deck);
        int prevSize = 0;
        for (Map.Entry<Integer, Integer> entry : countMap.entrySet()) {
            final Integer currentSize = entry.getValue();
            if (currentSize.equals(1)) {
                return false;
            }
            if (prevSize == 0) {
                prevSize = currentSize;
            } else {
                int gcd = Kit.gcd(prevSize, currentSize);
                if (gcd < 2) {
                    return false;
                } else {
                    prevSize = currentSize;
                }
            }
        }
        return true;
    }

    /**
     * 解题思路：计算每个数字出现的次数；如果数字出现的次数=1，false；每个数字次数，都相等，返回true
     * <br/> 与题目意思不符：[1,1,2,2,2,2]，可以分成[1,1],[2,2],[2,2]
     * 
     * @param deck
     * @return
     */
    public boolean hasGroupsSizeXError(int[] deck) {
        Map<Integer, Integer> countMap = Kit.countMap(deck);
        int prevSize = 0;
        for (Entry<Integer, Integer> entry : countMap.entrySet()) {
            final Integer currentSize = entry.getValue();
            if (currentSize.equals(1)) {
                return false;
            }
            if (prevSize == 0) {
                prevSize = currentSize;
            } else {
                if (prevSize != currentSize) {
                    return false;
                } else {
                    prevSize = currentSize;
                }
            }
        }
        return true;
    }
}
